# 计算联系人数据
import asyncio
import time

import pandas as pd
import warnings

from app.model_phl import utils
from app.model_phl import utils_sql
from app.model_phl import utils_json
from app.model_phl import util_log

warnings.filterwarnings('ignore')


def cal_con_contact_cnt(contact_df):
    """
    con_contact_cnt 通讯录联系人个数
    :param contact_df 通讯录数据
    """
    if isinstance(contact_df, pd.DataFrame):
        # 根据手机号统计，删除空数据，删除重复的手机号
        return contact_df.mobile.dropna().drop_duplicates().count()
    else:
        return 0


def cal_con_nameLen_0_6_dist(contact_df):
    """
    con_nameLen_0_6_dist 通讯录中姓名字符长度在[0,6]区间的通讯录个数 / 总通讯录个数
    :param contact_df 通讯录数据
    """
    if contact_df is None or contact_df.empty:
        return -999
    return contact_df.loc[
        (contact_df.get('name').str.len().between(0, 6))
    ].get('name').count()


def cal_con_nameLen_0_9_dist(contact_df):
    """
    con_nameLen_0_9_dist 通讯录中姓名字符长度在[0,9]区间的通讯录个数 / 总通讯录个数
    :param contact_df 通讯录数据
    """
    if contact_df is None or contact_df.empty:
        return -999
    return contact_df.loc[
        (contact_df.get('name').str.len().between(0, 9))
    ].get('name').count()


def cal_con_contact_fraudlevel1_cnt(contact_df):
    """
    con_contact_fraudlevel1_cnt 通讯录号码中FraudLevel = 1 的号码个数
    :param contact_df 通讯录数据
    """
    confraud_info_df = utils_json.get_confraud_info_data()
    # print(confraud_df)
    return contact_df.loc[
        # 反欺诈数据筛选
        (contact_df.get('mobile').isin(confraud_info_df.loc[(confraud_info_df.get('fraudLevel') == 1)].get('phone')))
    ].get('mobile').count()


async def cal_contact_features(contact_df):
    """
    计算联系人特征
    :param contact_df 通讯录数据
    """

    if contact_df is None or contact_df.empty:
        return {
            # 通讯录联系人个数:con_contact_cnt
            'con_contact_cnt': 0,
            # 通讯录中姓名字符长度在[0,6]区间的通讯录个数 / 总通讯录个数:con_nameLen_0_6_dist
            'con_nameLen_0_6_dist': 0,
            # 通讯录中姓名字符长度在[0,9]区间的通讯录个数 / 总通讯录个数:con_nameLen_0_9_dist
            'con_nameLen_0_9_dist': 0,
            # 通讯录号码中FraudLevel = 1 的号码个数:con_contact_fraudlevel1_cnt
            'con_contact_fraudlevel1_cnt': 0,
        }

    return {
        # 通讯录联系人个数:con_contact_cnt
        'con_contact_cnt': cal_con_contact_cnt(contact_df=contact_df),
        # 通讯录中姓名字符长度在[0,6]区间的通讯录个数 / 总通讯录个数:con_nameLen_0_6_dist
        'con_nameLen_0_6_dist': cal_con_nameLen_0_6_dist(contact_df=contact_df),
        # 通讯录中姓名字符长度在[0,9]区间的通讯录个数 / 总通讯录个数:con_nameLen_0_9_dist
        'con_nameLen_0_9_dist': cal_con_nameLen_0_9_dist(contact_df=contact_df),
        # 通讯录号码中FraudLevel = 1 的号码个数:con_contact_fraudlevel1_cnt
        'con_contact_fraudlevel1_cnt': cal_con_contact_fraudlevel1_cnt(contact_df=contact_df),
    }


if __name__ == '__main__':
    # 记录程序开始时间
    start_time = time.time()
    # utils.get_logger().error('eeee')
    print('联系人参数计算开始...')
    # 订单号
    apply_no = '170867419543331712'
    # apply_no = '167446013851750028'

    # 订单数据
    order_dict = utils_sql.get_mysql_order(apply_no)
    print("order_dict 程序运行时长：", time.time() - start_time, "秒")

    # 根据订单获取json文件路径
    json_file_url = utils_sql.get_mysql_json_url(apply_no)
    # 远程获取JSON数据
    json_string = utils.load_remote_json(json_file_url)
    # 将字符串转成json对象
    json_dict = utils.parse_json(json_string)
    print("json_dict 程序运行时长：", time.time() - start_time, "秒")

    # 联系人 相关参数计算
    con_string = json_dict.get('contacts')
    con_df = pd.read_json(con_string) if utils.is_json_string(con_string) else None
    con_features = asyncio.run(cal_contact_features(contact_df=con_df))
    print("con_features 程序运行时长：", time.time() - start_time, "秒")

    print(con_features)
